﻿using Enter.Dashboard.Api.Entities;
using Enter.Utils;
using Enter.Utils.CacheExt;
using Enter.Utils.CryptoExt;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Reflection;

namespace Enter.Dashboard.Api.Filters
{
    public enum AuthorizationRole
    { 
        User = 0,
        Admin = 1,
    }

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
    public class AuthorizationAttribute : Attribute
    {
        public AuthorizationAttribute()
        {
        }
        public AuthorizationRole Role { get; set; } = AuthorizationRole.User;
        public bool NeedLogin { get; set; } = true;
    }

    public class AuthorizationFilter : IActionFilter
    {
        private readonly IDistributedCache _cache;
        public AuthorizationFilter(IDistributedCache cache)
        {
            _cache = cache;
        }
        public void OnActionExecuting(ActionExecutingContext context)
        {
            var action = context.ActionDescriptor as ControllerActionDescriptor;
            var controller_permission = action.ControllerTypeInfo.GetCustomAttribute<AuthorizationAttribute>();
            var action_permission = action.MethodInfo.GetCustomAttribute<AuthorizationAttribute>();
            if (controller_permission == null && action_permission == null)
            {
                return;
            }
            var permission = action_permission == null ? controller_permission : action_permission;
            // 不需要登录;
            if (!permission.NeedLogin) 
            {
                return;
            }
            // 需要登录
            var tokenStr = context.HttpContext.GetToken();
            if (string.IsNullOrWhiteSpace(tokenStr))
            {
                var result = new ResponseData<string>("登录已过期.")
                {
                    Code = ResponseCode.NotLogin
                };
                context.Result = new JsonResult(result);
            }
            else
            {
                var token = TokenExtend.Pase(tokenStr);
                var session = _cache.Get<Employ>(token.Id);
                if (session == default(Employ))
                {
                    var result = new ResponseData<string>("登录已过期.")
                    {
                        Code = ResponseCode.NotLogin
                    };
                    context.Result = new JsonResult(result);
                }
                else if (!session.Role.IsDefault && permission.Role == AuthorizationRole.Admin)
                {
                    var result = new ResponseData<string>("没有权限.")
                    {
                        Code = ResponseCode.NotAuthorization
                    };
                    context.Result = new JsonResult(result);
                }
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            //filterContext.Result = new RedirectResult("customErrorPage.html");
            //context.HttpContext.Response.WriteAsync($"{GetType().Name} out. \r\n");
        }
    }
}
